﻿using WHLRDF.WF.BLL.Domain;
using System;
using System.Collections.Generic;
using System.Text;
using WHLRDF.ORM;
using WHLRDF.WF.Model;
using System.Linq;
using System.Threading.Tasks;
using WHLRDF.Log;

namespace WHLRDF.WF.BLL
{
    public class ProcessInstanceService : SerivceBase, IProcessInstanceService
    {
        public string Cache_ProcessFlow_Key = "Cache_ProcessFlow_Key_";

        public string Cache_Process_Instance_Key = "Cache_Process_Instance_Key_";

        private readonly static object locked = new object();

        private OrgFlowService _orgService;
        private OrgFlowService OrgService
        {
            get {
                if (_orgService == null)
                {
                    _orgService = new OrgFlowService();
                }
                return _orgService;
            }
        }

        /// <summary>
        /// 获取流程
        /// </summary>
        /// <param name="flowid"></param>
        /// <param name="version"></param>
        /// <returns></returns>
        public FlowVersionEty GetFlow(string flowid, int version = 0)
        {
            return this.GetFlow(flowid, version, false);
        }

        /// <summary>
        /// 获取流程
        /// </summary>
        /// <param name="flowid"></param>
        /// <param name="version"></param>
        /// <param name="isTest"></param>
        /// <returns></returns>
        //public ProcessFlow Process { get; set; }
        public FlowVersionEty GetFlow(string flowid, int version = 0, bool isTest = false)
        {
            FlowVersionEty processFlow = null;
            if (!isTest)
            {
                ICriterion where = Expression.And(Expression.Eq(FlowVersionEntity.__FlowId, flowid), Expression.Eq(FlowVersionEntity.__IsDeleted, false));
                if (version > 0)
                {
                    where = Expression.And(where, Expression.Eq(FlowVersionEntity.__Version, version));
                }
                var lst = this.Query<FlowVersionEntity>(where, Order.Desc(FlowVersionEntity.__Version));
                var versionEntity = new FlowVersionEntity();
                if (lst != null && lst.Count > 0)
                {
                    versionEntity = lst[0];
                }
                else
                {
                    return null;
                }
                processFlow = CacheService.GetOrCreate<FlowVersionEty>(Cache_ProcessFlow_Key + "_" + versionEntity.FlowId + "_" + versionEntity.Version.ToString(), () =>
                    {
                        if (lst != null && lst.Count > 0)
                        {
                            var process = new FlowVersionEty();
                            process.VersionEntity = versionEntity;
                            process.flowEty = this.GetById<FlowEntity>(flowid);
                            process.activities = this.Query<ActivityEntity>(Expression.And(Expression.Eq(ActivityEntity.__IsDeleted, false), Expression.Eq(ActivityEntity.__FlowId, lst[0].FlowVersionId)));
                            process.flowParams = this.Query<FlowParamsEntity>(Expression.And(Expression.Eq(FlowParamsEntity.__IsDeleted, false), Expression.Eq(ActivityEntity.__FlowId, lst[0].FlowVersionId)));
                            process.flowRules = this.Query<FlowRulesEntity>(Expression.And(Expression.Eq(FlowRulesEntity.__IsDeleted, false), Expression.Eq(FlowRulesEntity.__FlowId, lst[0].FlowVersionId)));
                            return process;
                        }
                        return null;
                    });
                return processFlow;
            }
            else
            {
                processFlow = new FlowVersionEty();
                var designer = new FlowService().GetFlowById(flowid);
                if (designer != null)
                {
                    processFlow.flowEty = designer.Flow;
                    processFlow.VersionEntity = new FlowVersionEntity
                    {
                        FlowId = flowid,
                        FlowVersionId = flowid + "_" + version,
                        Version = version,
                        ServiceClass=designer.Flow.ServiceClass,
                        OrderNum = version,
                        Status = true,
                    };
                    processFlow.activities = new List<ActivityEntity>();
                    foreach (var item in designer.activities)
                    {
                        processFlow.activities.Add(item.Value);
                    }
                    processFlow.flowParams = new List<FlowParamsEntity>();
                    foreach (var item in designer.flowParams)
                    {
                        processFlow.flowParams.Add(item.Value);
                    }
                    processFlow.flowRules = new List<FlowRulesEntity>();
                    foreach (var item in designer.flowRules)
                    {
                        foreach (var item1 in item.Value)
                        {
                            if (item1.Value.group != null)
                            {
                                item1.Value.Condition = item1.Value.group.ToJson();
                            }
                            processFlow.flowRules.Add(item1.Value);
                        }
                    }
                    foreach (var path in designer.paths)
                    {
                        processFlow.flowRules.Add(new FlowRulesEntity
                        {
                            FlowRuleId = path.Key,
                            ActivityId = path.Value.from,
                            ToActivity = path.Value.to,
                            FlowId = designer.Flow.FlowId,
                            FlowRuleName = path.Value.lineType,
                            FlowRuleType = path.Value.lineType.ToLower().Equals("path") ? 0 : 1,
                            IsPath=true,
                            ToType = 0,
                            Condition = ""
                        });
                        //activity.Value.FlowId = versionEntity.FlowVersionId;
                    }
                    return processFlow;
                }
            }
            return null;
        }

        /// <summary>
        /// 启动流程
        /// </summary>
        /// <param name="flowid"></param>
        /// <param name="fromId"></param>
        /// <param name="fromTitle"></param>
        /// <param name="senderUser"></param>
        /// <param name="parameters"></param>
        /// <param name="instanceId"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool Start(string flowid, string fromId, string fromTitle, string senderUser,
          FlowParameterCollection parameters, ref string instanceId, ref string strError)
        {
            return this.Start(flowid, 0, fromId, fromTitle, senderUser, parameters, ref instanceId, ref strError, false, false);
        }

       /// <summary>
       /// 启动流程
       /// </summary>
       /// <param name="flowid"></param>
       /// <param name="fromId"></param>
       /// <param name="fromTitle"></param>
       /// <param name="senderUser"></param>
       /// <param name="parameters"></param>
       /// <param name="instanceId"></param>
       /// <param name="strError"></param>
       /// <param name="isSubProcess"></param>
       /// <returns></returns>
        public bool Start(string flowid, string fromId, string fromTitle, string senderUser,
           FlowParameterCollection parameters, ref string instanceId, ref string strError, bool isSubProcess=false)
        {
            return this.Start(flowid, 0, fromId, fromTitle, senderUser, parameters, ref instanceId, ref strError, isSubProcess, false);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="flowid"></param>
        /// <param name="version"></param>
        /// <param name="fromId"></param>
        /// <param name="senderUser"></param>
        /// <param name="varParameters"></param>
        /// <param name="instanceId"></param>
        /// <param name="strError"></param>
        /// <param name="isTest"></param>
        /// <returns></returns>
        public bool Start(string flowid,
            int version, 
            string fromId,
            string fromTitle, 
            string senderUser,
            FlowParameterCollection varParameters, 
            ref string instanceId, ref string strError, 
            bool isSubProcess = false, bool isTest = false)
        {
            if (string.IsNullOrWhiteSpace(fromId)|| string.IsNullOrWhiteSpace(fromTitle))
            {
                strError = "流程表单参数为空或者标题为空";
                return false;
            }
           
            ProcessInstance instance = new ProcessInstance();
            instance.Flow = GetFlow(flowid, version, isTest);
            if (instance.Flow == null)
            {
                strError = "流程无法找到，无法启动";
                return false;
            }
            if (!isTest)
            {
                ICriterion criterion = Expression.And(Expression.Eq(ProcessEntity.__IsDeleted, false),
                    Expression.And(Expression.Eq(ProcessEntity.__FlowId, instance.Flow.flowEty.FlowId), 
                    Expression.And(Expression.Eq(ProcessEntity.__FromId, fromId),
                    Expression.Eq(ProcessEntity.__Version, instance.Flow.VersionEntity.Version))));
                ProcessEntity pInstance = this.Select<ProcessEntity>(criterion);
                if (pInstance != null)
                {
                    strError = "流程已经启动，无法再次发起";
                    return true;
                }
            }
            instance.Process = new ProcessEntity
            {
                FlowId = instance.Flow.flowEty.FlowId,
                Version = instance.Flow.VersionEntity.Version,
                FromId = fromId,
                Title=fromTitle,
                OperatorId = senderUser,
                OwnerUserId = senderUser,
                IsSubProcess=isSubProcess,
                StartDate=DateTime.Now,
                Status = InsStateEnum.Start.GetHashCode()
            };
            instance.Process.ProcessId = instanceId = MyGenerateHelper.GenerateOrder();
            var startActivity = instance.Flow.activities.Where(x => x.ActivityType == PhaseTypeEnum.start.GetHashCode()).FirstOrDefault();
            if (startActivity == null)
            {
                strError = "流程异常，无法启动";
                return false;
            }
            if (!CheckUser(startActivity, senderUser))
            {
                strError = "您无权启动流程！";
                return false;
            }
           // instance.lstParams = new List<ProcessParamEntity>();
            if (varParameters != null && varParameters.Count > 0)
            {
               this.ConvertParams( instance, varParameters);
            }
            var lstRules = this.GetToRule(instance,startActivity, LinkTypeEnum.Submit, ref strError);
            if (lstRules == null)
            {
                strError = "流程异常，无法启动";
                return false;
            }
            instance.taskEntities = new List<ProcessTaskEntity>();
            var task = new ProcessTaskEntity
            {
                SenderUserId = "系统",
                TaskLabel=startActivity.ActivityName,
                ProcessTaskId = MyGenerateHelper.GenerateOrder(instance.Process.ProcessId, 2),
                ActivityId = startActivity.ActivityId,
                ProcessId = instance.Process.ProcessId,
                SendDate=DateTime.Now,
                Description =  "流程启动" ,
                TaskRound = 0,
                AssignUser = "系统",
                OwnerUserId = senderUser,
                TaskType = TaskTypeEnum.NormalTask.GetHashCode(),
                Status = TaskStateEnum.Executed.GetHashCode()
            };
            task.FromTaskId = task.ProcessTaskId;
            bool isEnd = false;
            List<ProcessTaskEntity> taskEntities = new List<ProcessTaskEntity>();
            RunToTask(instance, lstRules,LinkTypeEnum.Submit,task, senderUser,ref taskEntities, ref isEnd);
            taskEntities.Add(task);
            if (!isTest)
            {
                using (var tran = this.Begin())
                {
                    try
                    {
                        this.Insert<ProcessEntity>(instance.Process, ref strError);
                        if (taskEntities != null && taskEntities.Count > 0)
                        {
                            this.BatchInsert<ProcessTaskEntity>(taskEntities,ref strError);
                        }
                        this.BatchInsert<ProcessParamEntity>(instance.lstParams,ref strError);
                        this.Commit();
                    }
                    catch (Exception ex)
                    {
                        this.Rollback();
                        throw ex;
                    }
                }
                CacheService.Add(Cache_Process_Instance_Key + instance.Process.ProcessId, instance);
            }
            else
            {
                CacheService.Add(Cache_Process_Instance_Key + instance.Process.ProcessId, instance);
            }
            RunProcessEvent(instance, InsStateEnum.Start);
            return true;
        }

        /// <summary>
        /// 验证发送用户是否有效
        /// </summary>
        /// <param name="activity"></param>
        /// <param name="senderUser"></param>
        /// <returns></returns>
        public bool CheckUser(ActivityEntity activity, string senderUser)
        {
            if (activity.RecipientType > 20)
            {
                return true;
            }
            switch ((RecipientType)activity.RecipientType)
            {
                case RecipientType.User:
                    return activity.RecipientName.Equals(senderUser);
                case RecipientType.Group:
                    return OrgService.CheckGroupUser(activity.OrgId, senderUser, activity.RecipientId);
                case RecipientType.Department:
                    return OrgService.CheckDepartmentUser(activity.OrgId, senderUser, activity.RecipientId);
                case RecipientType.JobFunction:
                    return OrgService.CheckJobFunctionUser(activity.OrgId, senderUser, activity.RecipientId);
            }
            return false;
        }

        /// <summary>
        /// 获取流程实例
        /// </summary>
        /// <param name="instanceId">实例id</param>
        /// <returns></returns>
        public ProcessInstance GetInstance(string instanceId)
        {
            ProcessInstance instance= CacheService.GetOrCreate<ProcessInstance>(Cache_Process_Instance_Key + instanceId,()=>{
                ProcessInstance pInstance = new ProcessInstance();
                pInstance.Process = this.GetById<ProcessEntity>(instanceId);
                if (pInstance.Process != null)
                {
                    pInstance.Flow = this.GetFlow(pInstance.Process.FlowId, pInstance.Process.Version);
                }
                return pInstance;
            });
            ICriterion criterion = Expression.And(Expression.Eq(ProcessParamEntity.__IsDeleted, false), Expression.Eq(ProcessParamEntity.__ProcessId, instanceId));
            instance.lstParams = this.Query<ProcessParamEntity>(criterion);
            criterion = Expression.And(Expression.Eq(ProcessTaskEntity.__IsDeleted, false), Expression.Eq(ProcessTaskEntity.__ProcessId, instanceId));
            instance.taskEntities = this.Query<ProcessTaskEntity>(criterion);
            return instance;
        }

        /// <summary>
        /// 获取目标节点
        /// </summary>
        /// <param name="pFlow">流程</param>
        /// <param name="fromActivity">来源节点</param>
        /// <param name="lstParams">参数</param>
        /// <param name="lstParams">节点类别</param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public List<FlowRulesEntity> GetToRule(ProcessInstance instance,
            ActivityEntity fromActivity, LinkTypeEnum typeEnum, ref string strError)
        {
            List<FlowRulesEntity> toRules = new List<FlowRulesEntity>();
            var rules = instance.Flow.flowRules.Where(x => x.ActivityId == fromActivity.ActivityId).ToList();
            if (rules == null || rules.Count <= 0)
            {
                strError = "流程节点中没有规则，请联系管理员！";
                return null;
            }
            var submitRules = rules.Where(x => x.FlowRuleType == typeEnum.GetHashCode()&&!x.IsPath).ToList();
            FlowRulesEntity toRule = null;
            if (submitRules == null || submitRules.Count <= 0)
            {
                toRule = rules.Where(x => x.FlowRuleType == typeEnum.GetHashCode() && x.IsPath).FirstOrDefault();
                if (toRule == null)
                {
                    strError = "流程节点中没有提交规则，请联系管理员！";
                    return null;
                }
                toRules.Add(toRule);
                return toRules;
            }
            foreach (var rule in submitRules)
            {
                if (CheckRule(rule, instance.flowParameters))
                {
                    toRules.Add(rule);
                }

            }
            return toRules;
        }

        #region ToTask

        /// <summary>
        /// 获取下级任务
        /// </summary>
        /// <param name="pFlow">流程</param>
        /// <param name="instance">实例id</param>
        /// <param name="lstRules">规则</param>
        /// <param name="fromActivityId"></param>
        /// <param name="fromUserId"></param>
        /// <returns></returns>
        public void RunToTask( ProcessInstance instance,
            List<FlowRulesEntity> lstRules,
            LinkTypeEnum typeEnum,
            ProcessTaskEntity fromTask,
            string fromUserId,
            ref List<ProcessTaskEntity> taskEntities,
            ref bool isEnd)
        {
            List<string> lstUsers = new List<string>();
            foreach (var rule in lstRules)
            {
                var toActivity = instance.Flow.activities.Where(x => x.ActivityId == rule.ToActivity).FirstOrDefault();
                if (toActivity == null)
                {
                    continue;
                }
               
                if (toActivity.ActivityType == PhaseTypeEnum.end.GetHashCode())
                {
                    isEnd = true;
                    //lstUsers.Add(fromUserId);
                    ////创建任务
                    //this.ToUserTasks(pFlow, instance, taskEntities, typeEnum, fromTask, lstUsers, fromUserId, toActivity,0,true);
                    return;
                }
                ProcessTaskEntity task1 = null;
                //验证是否可执行下级节点
                if (!CheckTasks( instance, typeEnum, fromTask, toActivity, ref task1))
                {
                    continue ;
                }
                int taskRound = 0;
                if (task1 != null)
                {
                    taskRound= task1.TaskRound++;
                }
                RunActiveEvent(instance, toActivity, fromTask, TaskStateEnum.Activated);
                
                if (LinkTypeEnum.Reject == typeEnum)//驳回时获取用户
                {
                    ICriterion where = Expression.And(Expression.Eq(ProcessTaskEntity.__Status, TaskStateEnum.Executed.GetHashCode()),
                        Expression.And(Expression.Eq(ProcessTaskEntity.__ActivityId, toActivity.ActivityId), Expression.Eq(ProcessTaskEntity.__IsDeleted, false)));
                    var lstTask = this.Query<ProcessTaskEntity>(where, Order.Desc(ProcessTaskEntity.__TaskRound));
                    if (lstTask != null && lstTask.Count > 0)
                    {
                        lstUsers.Add(lstTask[0].OwnerUserId);
                    }
                }
                else
                {
                    //获取审批用户
                    lstUsers = this.GetToTaskUser(instance, fromUserId, toActivity, fromTask.ProcessTaskId);
                }
                if (toActivity.ActivityType == PhaseTypeEnum.judge.GetHashCode())//判断节点
                {
                    
                    ToTaskJudge(instance, fromTask, toActivity,taskEntities, typeEnum, fromUserId);
                    continue;
                }
                if (toActivity.ActivityType == PhaseTypeEnum.queue.GetHashCode())//队列
                {
                    this.ToQueue(instance, taskEntities, typeEnum, fromTask, fromUserId, toActivity, taskRound);
                    continue;
                }
                if (toActivity.ActivityType == PhaseTypeEnum.subprocess.GetHashCode())
                {
                    lstUsers = new List<string>();
                    lstUsers.Add("");
                }
                //创建任务
                this.ToUserTasks( instance, taskEntities, typeEnum, fromTask,lstUsers, fromUserId, toActivity, taskRound);
                if (toActivity.ActivityType == PhaseTypeEnum.subprocess.GetHashCode())
                {
                   var totask= taskEntities.Where(x=>x.ActivityId==toActivity.ActivityId).FirstOrDefault();
                    if (totask != null)
                    {
                        totask.TaskType = TaskTypeEnum.SubProcessTask.GetHashCode();
                        totask.Status = TaskStateEnum.Activated.GetHashCode();
                    }
                    string instanceid = "";
                    string strError = "";
                    Task.Factory.StartNew(() => {
                        this.Start(toActivity.RecipientId, 0, totask.ProcessTaskId, totask.TaskLabel + "子流程", fromUserId, instance.flowParameters, ref instanceid, ref strError,true);
                    });
                   
                }
            }
            //this.BatchSave<ProcessTaskEntity>(taskEntities);

        }

        /// <summary>
        /// 判断节点
        /// </summary>
        /// <param name="pFlow">流程</param>
        /// <param name="instance">实例id</param>
        /// <param name="fromTask">上级task</param>
        /// <param name="toActivity">节点</param>
        /// <param name="typeEnum">枚举</param>
        /// <param name="fromUserId">用户id</param>
        /// <returns></returns>
        public bool ToTaskJudge(
            ProcessInstance instance,
            ProcessTaskEntity fromTask,
            ActivityEntity toActivity,
            List<ProcessTaskEntity> taskEntities,
            LinkTypeEnum typeEnum,
            string fromUserId)
        {
            
            string strError = "";
            List<string> lstUsers = new List<string>();
            lstUsers.Add(fromUserId);
           
           var fromActivity= instance.Flow.activities.Where(x => x.ActivityId == fromTask.ActivityId).FirstOrDefault();
            this.ToUserTasks( instance, taskEntities, typeEnum, fromTask, lstUsers, fromUserId, toActivity,0);
            if (taskEntities != null && taskEntities.Count > 0)
            {
                foreach (var taskEntity in taskEntities)
                {
                    taskEntity.Status = TaskStateEnum.Executed.GetHashCode();
                    taskEntity.EDate = DateTime.Now;
                    this.ToNextTask(instance, taskEntity, fromActivity, LinkTypeEnum.Submit, ref strError);
                }
            }
            return true;
        }

        /// <summary>
        /// 验证可执行下级节点
        /// </summary>
        /// <param name="pFlow">流程</param>
        /// <param name="instance">实例</param>
        /// <param name="typeEnum"></param>
        /// <param name="fromTask"></param>
        /// <param name="toActivity"></param>
        /// <param name="fristTask"></param>
        /// <returns></returns>
        private bool CheckTasks(
           ProcessInstance instance,
           LinkTypeEnum typeEnum,
           ProcessTaskEntity fromTask,
           ActivityEntity toActivity,
           ref ProcessTaskEntity fristTask)
        {
            ICriterion criterion = Expression.And(Expression.Eq(ProcessTaskEntity.__Status, TaskStateEnum.Executed.GetHashCode()),
                 Expression.And(Expression.Eq(ProcessTaskEntity.__ActivityId, toActivity.ActivityId),
                 Expression.Eq(ProcessTaskEntity.__IsDeleted, false)));
            var lstTasks = this.Query<ProcessTaskEntity>(criterion, Order.Desc(ProcessTaskEntity.__TaskRound));
            if (lstTasks != null && lstTasks.Count > 0)//多用户审批验证
            {
               
                fristTask = lstTasks[0];
                var tasks = lstTasks.Where(x => x.TaskRound == fromTask.TaskRound && x.Status == TaskStateEnum.Executed.GetHashCode()).ToList();
                int taskCount = 1;
                if (tasks != null && tasks.Count > 0)
                {
                    taskCount = tasks.Count + 1;
                   var result= instance.taskEntities.Where(x => tasks.Where(y => y.ProcessTaskId == x.FromTaskId).FirstOrDefault() != null).FirstOrDefault();//判断是否已执行下级节点
                    if (result != null)//已执行下级节点
                    {
                        return false;
                    }
                }
                if (toActivity.Mininum > 0)
                {
                    if (taskCount < toActivity.Mininum)
                    {
                        return false;
                    }
                }
                else
                {
                    int totalCount = lstTasks.Count(x => x.TaskRound == fromTask.TaskRound);
                    if (taskCount < totalCount)
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        /// <summary>
        /// 队列节点
        /// </summary>
        /// <param name="pFlow"></param>
        /// <param name="instance"></param>
        /// <param name="taskEntities"></param>
        /// <param name="typeEnum"></param>
        /// <param name="fromTask"></param>
        /// <param name="fromUserId"></param>
        /// <param name="toActivity"></param>
        /// <param name="taskRound"></param>
        private void ToQueue(
            ProcessInstance instance,
            List<ProcessTaskEntity> taskEntities,
            LinkTypeEnum typeEnum, 
            ProcessTaskEntity fromTask,
            string fromUserId,
            ActivityEntity toActivity,
            int taskRound=0)
        {
            if (toActivity.ActivityType == PhaseTypeEnum.queue.GetHashCode())//队列
            {
                var task = new ProcessTaskEntity
                {
                    SenderUserId = fromUserId,
                    TaskLabel = toActivity.ActivityName,
                    ProcessTaskId = MyGenerateHelper.GenerateOrder(instance.Process.ProcessId, 2),
                    FromTaskId = fromTask.ProcessTaskId,
                    ActivityId = toActivity.ActivityId,
                    ProcessId = instance.Process.ProcessId,
                    Description = "",
                    TaskRound = taskRound,
                    AssignUser = "",
                    SendDate = DateTime.Now,
                    OwnerUserId = toActivity.OrgId + "/" + toActivity.RecipientId,
                    TaskType = TaskTypeEnum.Queue.GetHashCode(),
                    Status = TaskStateEnum.Activated.GetHashCode()
                };
                taskEntities.Add(task);
                instance.taskEntities.Add(task);
            }
        }


        /// <summary>
        /// 创建用户任务
        /// </summary>
        /// <param name="pFlow">流程</param>
        /// <param name="instance">实例</param>
        /// <param name="taskEntities">任务</param>
        /// <param name="typeEnum">提交类别</param>
        /// <param name="fromTask">上一个task</param>
        /// <param name="lstUsers">用户列表</param>
        /// <param name="fromUserId">发送人</param>
        /// <param name="toActivity">当前任务</param>
        /// <param name="taskRound"></param>
        private void ToUserTasks(
             ProcessInstance instance,
             List<ProcessTaskEntity> taskEntities,
             LinkTypeEnum typeEnum,
             ProcessTaskEntity fromTask,
             List<string> lstUsers,
             string fromUserId,
             ActivityEntity toActivity,
             int taskRound = 0,
             bool isEdit=false)
        {
            string fristUser = "";
            if (lstUsers != null && lstUsers.Count > 0)
            {
                fristUser = lstUsers[0];
            }
            var task = new ProcessTaskEntity
            {
                SenderUserId = fromUserId,
                TaskLabel = toActivity.ActivityName,
                ProcessTaskId = MyGenerateHelper.GenerateOrder(instance.Process.ProcessId, 2),
                FromTaskId = fromTask.ProcessTaskId,
                ActivityId = toActivity.ActivityId,
                ProcessId = instance.Process.ProcessId,
                SendDate=DateTime.Now,
                Description = "",
                TaskRound = taskRound,
                AssignUser = isEdit?"":fristUser,
                OwnerUserId = isEdit ? "" : fristUser,
                TaskType =TaskTypeEnum.NormalTask.GetHashCode(),
                Status = isEdit ?TaskStateEnum.Executed.GetHashCode(): TaskStateEnum.Activated.GetHashCode()
            };
            taskEntities.Add(task);
            instance.taskEntities.Add(task);
            if (lstUsers != null && lstUsers.Count > 1)
            {
                for (var i = 1; i < lstUsers.Count; i++)
                {
                    if (string.IsNullOrWhiteSpace(lstUsers[i]))
                        continue;
                    var task1 = new ProcessTaskEntity
                    {
                        SenderUserId = fromUserId,
                        TaskLabel = toActivity.ActivityName,
                        ProcessTaskId = MyGenerateHelper.GenerateOrder(instance.Process.ProcessId, 2),
                        FromTaskId = fromTask.ProcessTaskId,
                        ActivityId = toActivity.ActivityId,
                        ProcessId = instance.Process.ProcessId,
                        Description = "",
                        SendDate = DateTime.Now,
                        TaskRound = taskRound,
                        AssignUser = lstUsers[i],
                        OwnerUserId = lstUsers[i],
                        TaskType = TaskTypeEnum.NormalTask.GetHashCode(),
                        Status = TaskStateEnum.Activated.GetHashCode()
                    };
                    taskEntities.Add(task1);
                    instance.taskEntities.Add(task1);

                }
            }
        }

        /// <summary>
        /// 创建下一个节点任务
        /// </summary>
        /// <param name="pFlow"></param>
        /// <param name="instance"></param>
        /// <param name="varParameters"></param>
        /// <param name="fromTask"></param>
        /// <param name="typeEnum"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        private bool ToNextTask(
            ProcessInstance instance,
            ProcessTaskEntity fromTask,
            ActivityEntity fromActivity,
            LinkTypeEnum typeEnum,
            ref string strError
            )
        {
            List<ProcessTaskEntity> taskEntities = new List<ProcessTaskEntity>();
            //转换流程参数 
            bool isEnd = false;
            if (fromActivity != null)//获取规则
            {
                RunActiveEvent(instance, fromActivity, fromTask, (LinkTypeEnum.Submit == typeEnum ? TaskStateEnum.Executed : TaskStateEnum.Paused));
                var lstRules = GetToRule(instance,fromActivity, typeEnum, ref strError);
                if (lstRules != null && lstRules.Count > 0)
                {
                    RunToTask( instance, lstRules, typeEnum, fromTask, fromTask.AssignUser,ref taskEntities, ref isEnd);
                }
            }
            if (isEnd)
            {
                string str = "";
                if(instance.Process.IsSubProcess)///子流程
                {
                    Task.Factory.StartNew(() => {
                        RunTask(instance.Process.FromId, instance.flowParameters, LinkTypeEnum.Submit, fromTask.AssignUser, "", ref str);
                    });
                }
                
               
            }
            using (var tran = this.Begin())
            {
                try
                {
                    if (isEnd)
                    {
                        this.End(instance, fromTask.AssignUser,InsStateEnum.End,ref strError,false);
                    }
                    if (taskEntities != null && taskEntities.Count > 0)
                    {
                        this.BatchSave<ProcessTaskEntity>(taskEntities);
                      //  this.BatchSave<ProcessParamEntity>(instance.taskParams);
                    }
                   
                    this.Commit();
                }
                catch (Exception ex)
                {
                    this.Rollback();
                    throw ex;
                }
            }
            if (isEnd)
            {
                RunProcessEvent( instance, InsStateEnum.End);
            }
            return true;
        }

        /// <summary>
        /// 获取具体的任务执行者
        /// </summary>
        /// <param name="process">流程</param>
        /// <param name="instance">实例</param>
        /// <param name="senderUserId">用户</param>
        /// <param name="toActivity">下级任务</param>
        /// <param name="fromtaskId">当前任务节点id</param>
        /// <returns></returns>
        public List<string> GetToTaskUser( ProcessInstance instance,
            string senderUserId, ActivityEntity toActivity, string fromtaskId)
        {
            if (toActivity == null)
            {
                return null;
            }
            List<string> lstUser = new List<string>();

            FlowParameter paramEntity = null;
            paramEntity = instance.flowParameters.Where(x => x.ParameterName.Equals(toActivity.RecipientName)).FirstOrDefault();
            ProcessTaskEntity processTask = null;
            ICriterion criterion = null;
            string toUserId = "";
            switch ((RecipientType)toActivity.RecipientType)
            {
                case RecipientType.User:
                    lstUser.Add(toActivity.RecipientId);
                    break;
                case RecipientType.Department:
                    lstUser = OrgService.GetUserByDepartment(toActivity.OrgId, toActivity.RecipientId);
                    break;
                case RecipientType.JobFunction:
                    toUserId = OrgService.GetUserByJobFunction(toActivity.OrgId, toActivity.RecipientId);
                    break;
                case RecipientType.Group:
                    lstUser = OrgService.GetUserByGroup(toActivity.OrgId, toActivity.RecipientId);
                    break;
                case RecipientType.Dynamic_Recipient:
                    var arr = (paramEntity != null ? paramEntity.ParameterValue : "").Split(new char[] { ',', ';' });
                    foreach (var item in arr)
                    {
                        if (!string.IsNullOrWhiteSpace(item))
                        {
                            lstUser.Add(item);
                        }
                    }
                    break;
                case RecipientType.Supervisor_Dynamic_Recipient:
                    if (paramEntity != null)
                    {
                        toUserId = OrgService.GetSuperiorByUser(toActivity.OrgId, paramEntity.ParameterValue);
                    }
                    break;
                case RecipientType.Manager_Dynamic_Recipient:
                    if (paramEntity != null)
                    {
                        toUserId = OrgService.GetManagerByUser(toActivity.OrgId, paramEntity.ParameterValue);
                    }
                    break;
                case RecipientType.Supervisor:
                    criterion = Expression.Eq(ProcessTaskEntity._PrimaryKeyName, fromtaskId);
                    processTask = this.Select<ProcessTaskEntity>(criterion);
                    if (processTask != null)
                    {
                        toUserId = OrgService.GetSuperiorByUser(toActivity.OrgId, processTask.OwnerUserId);
                    }
                    break;
                case RecipientType.ManagerStep:
                    criterion = Expression.Eq(ProcessTaskEntity._PrimaryKeyName, fromtaskId);
                    processTask = this.Select<ProcessTaskEntity>(criterion);
                    if (processTask != null)
                    {
                        toUserId = OrgService.GetManagerByUser(toActivity.OrgId, processTask.OwnerUserId);
                    }
                    break;
                case RecipientType.PreviousStep:
                    criterion = Expression.Eq(ProcessTaskEntity._PrimaryKeyName, fromtaskId);
                    processTask = this.Select<ProcessTaskEntity>(criterion);
                    if (processTask != null)
                    {
                        toUserId = processTask.OwnerUserId;
                    }
                    break;
                case RecipientType.Supervisor_Previous_Step:
                    criterion = Expression.Eq(ProcessTaskEntity._PrimaryKeyName, fromtaskId);
                    processTask = this.Select<ProcessTaskEntity>(criterion);
                    if (processTask != null)
                    {
                        toUserId = OrgService.GetUserBySuperior(toActivity.OrgId, processTask.OwnerUserId);
                    }
                    break;
                case RecipientType.Manager_Previous_Step:
                    criterion = Expression.Eq(ProcessTaskEntity._PrimaryKeyName, fromtaskId);
                    processTask = this.Select<ProcessTaskEntity>(criterion);
                    if (processTask != null)
                    {
                        toUserId = OrgService.GetManagerByUser(toActivity.OrgId, processTask.OwnerUserId);
                    }
                    break;

                case RecipientType.SenderStep:
                    toUserId = instance.Process.OperatorId;
                    break;

            }
            if (!string.IsNullOrWhiteSpace(toUserId))
            {
                lstUser.Add(toUserId);
            }

            return lstUser;
        }

        /// <summary>
        /// 转换流程参数
        /// </summary>
        /// <param name="process"></param>
        /// <param name="instance"></param>
        /// <param name="varParameters"></param>
        public void ConvertParams(ProcessInstance instance, FlowParameterCollection varParameters)
        {
            instance.flowParameters = varParameters;
            if (instance.flowParameters == null)
            {
                instance.flowParameters = new FlowParameterCollection();
            }
            if (instance.lstParams == null)
            {
                instance.lstParams = new List<ProcessParamEntity>();
            }
            if (varParameters != null && varParameters.Count > 0)
            {
                foreach (var paramEntity in instance.lstParams)
                {
                    var value = instance.flowParameters.Where(x => x.ParameterName.ToLower().Equals(paramEntity.ParamName.ToLower()));
                    if (value != null)
                    {
                        continue;
                    }
                    instance.flowParameters.Add(paramEntity.ParamName, paramEntity.ParamValue);

                }
                foreach (var parameter in varParameters)
                {
                    var param1 = instance.lstParams.Where(x => x.ParamName.ToLower().Equals(parameter.ParameterName.ToLower())).FirstOrDefault();
                    if (param1 == null)
                    {
                        var param = instance.Flow.flowParams.Where(x => x.FlowParamName.ToLower().Equals(parameter.ParameterName.ToLower())).FirstOrDefault();
                        if (param == null)
                        {
                            throw new Exception("参数不存在");
                        }
                        instance.lstParams.Add(new ProcessParamEntity
                        {
                            FlowParamId = param.FlowParamId,
                            ParamName = parameter.ParameterName,
                            ProcessId = instance.Process.ProcessId,
                            ProcessTaskId = "",
                            ParamValue = parameter.ParameterValue,
                            Status = 0
                        });
                    }
                    else
                    {
                        param1.ParamValue = parameter.ParameterValue;
                    }
                }

            }
           
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="taskid"></param>
        /// <param name="varParameters"></param>
        /// <param name="typeEnum"></param>
        /// <param name="senderUserId"></param>
        /// <param name="description"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool RunTask(string taskid,
          FlowParameterCollection varParameters,
          LinkTypeEnum typeEnum,
          string senderUserId,
          string description,
          ref string strError )
        {
            return RunTask(taskid, varParameters, typeEnum, senderUserId, description, ref strError);
        }

        /// <summary>
        /// 运行
        /// </summary>
        /// <param name="instanceId">实例</param>
        /// <param name="taskid">任务id</param>
        /// <param name="varParameters">参数</param>
        /// <param name="typeEnum">类别</param>
        /// <param name="senderUserId">用户</param>
        /// <param name="description">意见</param>
        /// <param name="strError"></param>
        /// <param name="isTest"></param>
        /// <returns></returns>
        public bool RunTask(string taskid,
            FlowParameterCollection varParameters, 
            LinkTypeEnum typeEnum, 
            string senderUserId,
            string description,
            ref string strError,
            bool isSubProcess = false,
            bool isTest = false)
        {
            lock (locked)
            {
                var task = this.GetTaskById(taskid);
                if (task == null)
                {
                    strError = "任务不存在，无法运行";
                    return false;
                }
                var instance = this.GetInstance(task.ProcessId);
                if (instance == null)
                {
                    return false;
                }
                var fromActivity = instance.Flow.activities.Where(x => x.ActivityId == task.ActivityId).FirstOrDefault();
                if (fromActivity != null &&
                    (fromActivity.ActivityType == PhaseTypeEnum.start.GetHashCode()
                    || fromActivity.ActivityType == PhaseTypeEnum.end.GetHashCode()
                     || fromActivity.ActivityType == PhaseTypeEnum.subprocess.GetHashCode()))
                {
                    if (typeEnum == LinkTypeEnum.Reject)
                    {
                        strError = "任务无法回退";
                        return false;
                    }
                }
                if (task.TaskType == TaskTypeEnum.SubProcessTask.GetHashCode())
                {
                    task.AssignUser = senderUserId;
                    task.OwnerUserId = senderUserId;
                }
                if (task.Status == TaskStateEnum.Executed.GetHashCode())
                {
                    strError = "任务已完成,无法再次执行！";
                    return false;
                }
                task.Status = TaskStateEnum.Executed.GetHashCode();
                task.AssignUser = senderUserId;
                task.Description = description;
                task.EDate = DateTime.Now;
                this.ConvertParams(instance, varParameters);
                if (!isTest)
                {
                    using (var tran = this.Begin())
                    {
                        try
                        {
                            this.SaveOrUpdate<ProcessTaskEntity>(task);
                            this.BatchSave<ProcessParamEntity>(instance.taskParams);
                            this.Commit();
                        }
                        catch (Exception ex)
                        {
                            this.Rollback();
                            throw ex;
                        }
                    }
                }


                ToNextTask(instance, task, fromActivity, typeEnum, ref strError);
                CacheService.Add(Cache_Process_Instance_Key + instance.Process.ProcessId, instance);
                return true;
            }
            
        }

        #endregion 


        /// <summary>
        /// 通过任务id获取实例
        /// </summary>
        /// <param name="taskid"></param>
        /// <returns></returns>
        public ProcessTaskEntity GetTaskById(string taskid)
        {
           return  this.GetById<ProcessTaskEntity>(taskid);
        }

        public bool Abort(string instanceId, string userid, ref string strError)
        {
            var instance = this.GetInstance(instanceId);
            return this.End(instance, userid, InsStateEnum.Stop,ref strError,false);
        }

        /// <summary>
        /// 取消
        /// </summary>
        /// <param name="instanceId">流程实例id</param>
        /// <param name="userid">用户id</param>
        /// <param name="strError"></param>
        /// <param name="isTest"></param>
        /// <returns></returns>
        public bool Abort(string instanceId, string userid, ref string strError, bool isTest = false)
        {

            var instance = this.GetInstance(instanceId);
            return this.End(instance, userid,InsStateEnum.Stop,ref strError);
        }

        /// <summary>
        /// 流程结束
        /// </summary>
        /// <param name="instanceId"></param>
        /// <param name="userid"></param>
        /// <param name="stateEnum"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        private bool End(ProcessInstance instance, string userid, InsStateEnum stateEnum, ref string strError, bool isTest = false)
        {
            if (instance == null)
            {
                return false;
            }
            if (instance.Process.Status > InsStateEnum.Normal.GetHashCode())
            {
                strError = "流程异常，无法终止";
                return false;
            }
            FlowVersionEty pFlow = this.GetFlow(instance.Process.FlowId, instance.Process.Version, isTest);
            instance.Process.Status = stateEnum.GetHashCode() ;
            instance.Process.EndDate = DateTime.Now;
            instance.Process.OperatorId = userid;
            ///终止时需要执行的值
            ICriterion criterion = Expression.And(Expression.Lt(ProcessTaskEntity.__Status, TaskStateEnum.Executed.GetHashCode()), Expression.And(Expression.Eq(ProcessTaskEntity.__IsDeleted, 0), Expression.Eq(ProcessTaskEntity.__ProcessId, instance.Process.ProcessId)));
            ProcessTaskEntity taskEntity = new ProcessTaskEntity();
           
            taskEntity.Status = TaskStateEnum.Executed.GetHashCode();
            taskEntity.EDate = DateTime.Now;
            taskEntity.AssignUser = userid;
            using (var tran = this.Begin())
            {
                try
                {
                    this.SaveOrUpdate<ProcessEntity>(instance.Process);
                    if (stateEnum == InsStateEnum.Stop)
                    {
                        this.Update<ProcessTaskEntity>(taskEntity, criterion);
                    }
                    this.Commit();
                }
                catch (Exception ex)
                {
                    this.Rollback();
                    throw ex;
                }
            }

            RunProcessEvent(instance, stateEnum);
            return true;
        }

        #region 验证规则
        /// <summary>
        /// 验证规则值是否正确
        /// </summary>
        /// <param name="group"></param>
        /// <param name="groupOp"></param>
        /// <param name="valuePairs"></param>
        /// <returns></returns>
        private bool CheckGroupRules(GroupFilter group,
            string groupOp, FlowParameterCollection flowParameters)
        {
            if (group == null) return true;
            bool checkFlag = false;
            if (group.rules != null)
            {
                for (int i = 0; i < group.rules.Count; i++)
                {
                    checkFlag = CheckRule(group, group.rules[i], group.op, flowParameters);
                    if (group.op.ToLower().Equals("or"))
                    {
                        if (checkFlag)
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (!checkFlag)
                        {
                            break;
                        }
                    }
                }
            }
            if (checkFlag && group.groups != null)
            {
                foreach (var subgroup in group.groups)
                {
                    checkFlag = CheckGroupRules(subgroup, subgroup.op, flowParameters);

                }
            }
            return checkFlag;
        }
        
        /// <summary>
        /// 规则验证是否正确
        /// </summary>
        /// <param name="rule"></param>
        /// <param name="lstParams"></param>
        /// <returns></returns>
        private bool CheckRule(FlowRulesEntity rule, FlowParameterCollection flowParameters)
        {
            if (rule != null && !rule.IsPath && !string.IsNullOrWhiteSpace(rule.Condition))
            {
                var group = JSONHelper.FromJson<GroupFilter>(rule.Condition);
                bool checkflag = CheckGroupRules(group, group.op, flowParameters);
                return checkflag;
            }
            else
            {

                return true;
            }

        }

        /// <summary>
        /// 验证规则
        /// </summary>
        /// <param name="group">规则组</param>
        /// <param name="rule">单个规则</param>
        /// <param name="groupOp">操作符</param>
        /// <param name="lstParams">参数值</param>
        /// <returns></returns>
        public bool CheckRule(GroupFilter group, RuleFilter rule, string groupOp, FlowParameterCollection flowParameters)
        {

            string value = "";
            if (flowParameters != null && flowParameters.Count > 0)
            {
                var param = flowParameters.Where(x => x.ParameterName.ToLower() == rule.field.ToLower()).FirstOrDefault();
                if (param != null)
                {
                    value = param.ParameterValue.ToString();
                }
            }
            switch (rule.op.ToLower())
            {
                case "equal":
                    return value.ToLower().Equals(rule.value.ToLower());
                case "notequal":
                    return !value.ToLower().Equals(rule.value.ToLower());
                case "greater"://>
                    return value.ToLower().CompareTo(rule.value.ToLower()) > 0;
                case "greaterorequal"://>=
                    return value.ToLower().CompareTo(rule.value.ToLower()) >= 0;
                case "less": //<
                    return value.ToLower().CompareTo(rule.value.ToLower()) < 0;
                case "lessorequal"://<=
                    return value.ToLower().CompareTo(rule.value.ToLower()) <= 0;
                default: //
                    return value.ToLower().Equals(rule.value.ToLower());
            }
        }
        #endregion

        /// <summary>
        /// 获取实例流程图
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns></returns>
        public FlowDesigner GetFlowDesignerByInstance(string instanceId)
        {
            var instance= this.GetInstance(instanceId);
            if (instance == null)
            {
                return null;
            }
            ICriterion criterion = Expression.And(Expression.Ge(ProcessTaskEntity.__Status, TaskStateEnum.Activated.GetHashCode()), 
                Expression.And(Expression.Eq(ProcessTaskEntity.__IsDeleted, false), Expression.Eq(ProcessTaskEntity.__ProcessId, instanceId)));
            instance.taskEntities = this.Query<ProcessTaskEntity>(criterion,Order.Desc(ProcessTaskEntity.__LastModifyDate));
            var designer= new FlowService().GetFlowById(instance.Process.FlowId, instance.Process.Version);
            if (designer == null)
            {
                return null;
            }
            designer.Flow.FlowName = instance.Process.Title;
            var flowid = instance.Process.FlowId + instance.Process.Version.ToString().PadLeft(3,'0');
            List<string> removeKey = new List<string>();
            if (instance.taskEntities != null && instance.taskEntities.Count > 0)
            {
                foreach (var taskEntity in instance.taskEntities)
                {
                    if (taskEntity.FromTaskId == taskEntity.ProcessTaskId)
                        continue;
                    string toActivity = taskEntity.ActivityId.Replace(flowid, designer.Flow.FlowId);
                    if (designer.states.ContainsKey(toActivity))
                    {
                        designer.states[toActivity].IsActive = true;
                    }
                    var fromtask = instance.taskEntities.Where(x=>x.ProcessTaskId== taskEntity.FromTaskId).FirstOrDefault();
                    if (fromtask != null)
                    {
                        string fromActivity = fromtask.ActivityId.Replace(flowid, designer.Flow.FlowId);
                        var path=  (from x in designer.paths where
                         x.Value.@from == fromActivity
                         && x.Value.to == toActivity
                         select new FlowDesignerPhaseLink
                         {
                             dots = x.Value.dots,
                             @from = x.Value.@from,
                             to = x.Value.to,
                             IsActive = true,
                             lineType = x.Value.lineType,
                             path_arr = x.Value.path_arr,
                             path_p = x.Value.path_p,
                             text = x.Value.text,
                             pathKey=x.Key.Replace(flowid, designer.Flow.FlowId)

                         }).FirstOrDefault();
                        if (path != null)
                        {
                            if (path.pathKey.IndexOf(designer.Flow.FlowId)>=0|| path.pathKey.IndexOf(flowid) >= 0)
                            {
                                removeKey.Add(path.pathKey);
                                designer.paths.Remove(path.pathKey);
                            }
                           
                            path.text.text = taskEntity.AssignUser+"意见：" + taskEntity.Description;
                            designer.paths.Add(taskEntity.ProcessTaskId, path);
                        }
                    }
                }
            }
            return designer;
        }

        /// <summary>
        /// 流程实例 事件
        /// </summary>
        /// <param name="pFlow"></param>
        /// <param name="process"></param>
        /// <param name="stateEnum"></param>
        public void RunProcessEvent(ProcessInstance instance,InsStateEnum stateEnum)
        {
            Task.Factory.StartNew(() =>
            {
                try
                {
                    if (instance.Flow.EventListener != null)
                    {
                        instance.Flow.EventListener.ProcessListener(instance, stateEnum);
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error(this, ex);
                }
            });
        }

        /// <summary>
        /// 节点事件执行
        /// </summary>
        /// <param name="instance">流程实例</param>
        /// <param name="activityEntity">任务节点</param>
        /// <param name="fromTask">来源task</param>
        /// <param name="stateEnum">状态</param>
        public void RunActiveEvent(ProcessInstance instance, 
            ActivityEntity activityEntity,
            ProcessTaskEntity fromTask, 
            TaskStateEnum stateEnum)
        {
            if (activityEntity == null || !activityEntity.IsListener)
            {
                return;
            }
            Task.Factory.StartNew(() =>
            {
                try
                {
                    if (instance.Flow.EventListener != null)
                    {
                        instance.Flow.EventListener.ActivityListener(instance,activityEntity, fromTask, stateEnum);
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error(this,ex);
                }
            });
        }


        /// <summary>
        /// 获取待办事项
        /// </summary>
        /// <param name="ligerGrid"></param>
        /// <param name="userid"></param>
        /// <returns></returns>
        public LigerGrid MyTask(LigerGrid ligerGrid, string userid)
        {
            ICriterion criter = Expression.Eq("IsDeleted", false);
            if (!string.IsNullOrEmpty(ligerGrid.keyWord))
            {
                criter = Expression.And(criter,
                   Expression.Like(new string[] {
                        "b."+ProcessTaskEntity._PrimaryKeyName ,
                        "b."+ ProcessTaskEntity.__ProcessId ,
                        "a."+  ProcessEntity.__Title,
                        "a."+ ProcessEntity.__FromId,
                        "b."+  ProcessTaskEntity.__OwnerUserId,
                        "b."+  ProcessTaskEntity.__AssignUser
                   }, ligerGrid.keyWord)
                   );
            }
            criter= Expression.And(criter,
                    Expression.And(Expression.Eq("b." + ProcessTaskEntity.__Status, TaskStateEnum.Activated),
               Expression.Or( Expression.Eq("b." + ProcessTaskEntity.__AssignUser, userid),
               Expression.Eq("b." + ProcessTaskEntity.__OwnerUserId, userid))));
            string taskStatus = ligerGrid.GetValue("b.Status");
            string processStatus = ligerGrid.GetValue("a.Status");
            string flowId = ligerGrid.GetValue("FlowId");
            if (!string.IsNullOrWhiteSpace(flowId))
            {
                criter = Expression.And(criter, Expression.Eq("a." + ProcessEntity.__FlowId, flowId));
            }
            if (!string.IsNullOrWhiteSpace(taskStatus))
            {
                criter = Expression.And(criter, Expression.Eq("b." + ProcessTaskEntity.__Status, taskStatus));
            }
            if (!string.IsNullOrWhiteSpace(processStatus))
            {
                criter = Expression.And(criter, Expression.Eq("a." + ProcessEntity.__Status, processStatus));
            }
            if (string.IsNullOrWhiteSpace(ligerGrid.sortOrder))
            {
                ligerGrid.sortOrder = "desc";
            }
            if (string.IsNullOrWhiteSpace(ligerGrid.sortName))
            {
                ligerGrid.sortName = "b." + EntityBase.__LastModifyDate;
            }
            StringBuilder strsql = new StringBuilder("");
            strsql.Append(@"select a.ProcessId,a.Title,a.Status as ProcessStatus,b.Status as TaskStatus,b.ProcessTaskId,b.TaskLabel,
                b.AssignUser,b.OwnerUserId,b.ActivityId,b.Description,b.LastModifyDate,b.SendDate,b.EDate
                 from WF_Process as a
                inner join WF_ProcessTask  as b on a.ProcessId=b.ProcessId where a.IsDeleted=0 and b.IsDeleted=0 {0} ");
            return this.Query<MyTaskEntity>(strsql.ToString(),ligerGrid, criter);
        }

        /// <summary>
        /// 获取所有任务
        /// </summary>
        /// <param name="ligerGrid"></param>
        /// <param name="userid"></param>
        /// <returns></returns>
        public LigerGrid MyTodoList(LigerGrid ligerGrid,string userid)
        {
            ICriterion criter = Expression.Eq("a.IsDeleted", false);
            if (!string.IsNullOrEmpty(ligerGrid.keyWord))
            {
                criter = Expression.And(criter,
                    Expression.Like(new string[] {
                        "b."+ProcessTaskEntity._PrimaryKeyName ,
                        "b."+ ProcessTaskEntity.__ProcessId ,
                        "a."+  ProcessEntity.__Title,
                        "a."+ ProcessEntity.__FromId,
                        "b."+  ProcessTaskEntity.__OwnerUserId,
                        "b."+  ProcessTaskEntity.__AssignUser
                    }, ligerGrid.keyWord)
                    );
            }
            //criter= Expression.And(criter,
            // //   Expression.And(Expression.Eq(ProcessTaskEntity.__Status, TaskStateEnum.Activated),
            //   Expression.Or(Expression.Eq("b."+ProcessTaskEntity.__OperatorId, userid), 
            //   Expression.Eq("b." + ProcessTaskEntity.__OwnerUserId, userid)));
            string taskStatus = ligerGrid.GetValue("taskStatus");
            string processStatus = ligerGrid.GetValue("processStatus");
            string flowId = ligerGrid.GetValue("FlowId");
            if (!string.IsNullOrWhiteSpace(flowId))
            {
                criter = Expression.And(criter, Expression.Eq("a." + ProcessEntity.__FlowId, flowId));
            }
            if (!string.IsNullOrWhiteSpace(taskStatus))
            {
                criter = Expression.And(criter, Expression.Eq("b."+ProcessTaskEntity.__Status, taskStatus));
            }
            if (!string.IsNullOrWhiteSpace(processStatus))
            {
                criter = Expression.And(criter, Expression.Eq("a." + ProcessEntity.__Status, processStatus));
            }
            if (string.IsNullOrWhiteSpace(ligerGrid.sortOrder))
            {
                ligerGrid.sortOrder = "desc";
            }
            if (string.IsNullOrWhiteSpace(ligerGrid.sortName))
            {
                ligerGrid.sortName ="b."+ EntityBase.__LastModifyDate;
            }
            StringBuilder strsql = new StringBuilder("");
            strsql.Append(@"select a.ProcessId,a.Title,a.Status as ProcessStatus,b.Status as TaskStatus,b.ProcessTaskId,b.TaskLabel,
                b.AssignUser,b.OwnerUserId,b.ActivityId,b.Description,b.LastModifyDate,b.SendDate,b.EDate
                 from WF_Process as a
                inner join WF_ProcessTask  as b on a.ProcessId=b.ProcessId where a.IsDeleted=0 and b.IsDeleted=0 {0} ");
            return this.Query<MyTaskEntity>(strsql.ToString(),ligerGrid, criter);
        }

        /// <summary>
        /// 任务指派
        /// </summary>
        /// <param name="taskId"></param>
        /// <param name="userid"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool TaskAssignUser(string taskId, string userid,ref string strError)
        {
            var task= this.GetTaskById(taskId);
            if (task == null)
            {
                strError = "任务不存在，无法指派";
                return false;
            }
            if (string.IsNullOrWhiteSpace(userid))
            {
                strError = "用户为空，无法指派";
                return false;
            }
            if (task.Status >= TaskStateEnum.Executed.GetHashCode())
            {
                strError = "任务已完成，无法指派";
                return false;
            }
            if (task.TaskType==TaskTypeEnum.SubProcessTask.GetHashCode())
            {
                strError = "任务无法指派";
                return false;
            }
            task.OwnerUserId = userid;
            task.AssignUser = userid;
            this.SaveOrUpdate(task);
            return true;
        }


        /// <summary>
        /// 激活任务
        /// </summary>
        /// <param name="taskId"></param>
        /// <param name="userid"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool ActiveQueueTask(string taskId, string userid, ref string strError)
        {
            var task = this.GetTaskById(taskId);
            if (task == null)
            {
                strError = "任务不存在，无法指派";
                return false;
            }
            if (string.IsNullOrWhiteSpace(userid))
            {
                strError = "用户为空，无法指派";
                return false;
            }
            if (task.Status >= TaskStateEnum.Activated.GetHashCode())
            {
                if (task.OwnerUserId.Equals(userid))
                {
                    return true;
                }
                strError = "任务已激活，无法激活";
                return false;
            }
            task.OwnerUserId = userid;
            task.AssignUser = userid;
            task.Status = TaskStateEnum.Activated.GetHashCode();
           return this.Update<ProcessTaskEntity>(task);
            
        }

        /// <summary>
        /// 任务取消激活
        /// </summary>
        /// <param name="taskId"></param>
        /// <param name="userid"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool UnActiveQueueTask(string taskId,string userid,  ref string strError)
        {
            var task = this.GetTaskById(taskId);
            if (task == null)
            {
                strError = "任务不存在，无法指派";
                return false;
            }
            if (string.IsNullOrWhiteSpace(userid))
            {
                strError = "用户为空，无法指派";
                return false;
            }
            if (task.Status < TaskStateEnum.Activated.GetHashCode())
            {
                strError = "任务尚未激活";
                return false;
            }
            task.OwnerUserId = "";
            task.AssignUser = "";
            task.Status = TaskStateEnum.NotActive.GetHashCode();
            return this.Update<ProcessTaskEntity>(task);

        }

    }
}
